package com.yinwq.shorturl.utils;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {
    protected final static Logger logger = LoggerFactory.getLogger(StringUtil.class);

	public static Pattern ILLEGAL_PATTERN = Pattern
			.compile("[()‘|'<>（）]");

	/**
	 * 判断手机号码是否有效 增加了14x,17x的手机号码判断
	 * 
	 * @param num
	 * @return true 是正确的手机号码;
	 */
	public static boolean isMobileNum(String num) {
		if (isNullOrEmpty(num))
			return false;
		Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(17[0-9])|(15[0-9])|(18[0-9]))\\d{8}$");
		Matcher m = p.matcher(num);
		return m.matches();
	}

	/**
	 * 判断手机号码是否有效 增加了14x,17x的手机号码判断
	 * 
	 * @param num
	 * @return true 是正确的手机号码;
	 */
	public static String IllegalCharacter(String params) {
		Matcher m = ILLEGAL_PATTERN.matcher(params);
		return m.replaceAll("").trim();
	}

	/**
	 * 参数检测，判断是否为 null 或者 ""
	 * 
	 * @param needCheck
	 *            : 待检测字符串
	 * @return true: 输入字符串为 null 或者trim后为""<br>
	 *         false：输入字符串 不为null 并且 trim后不等于 ""
	 */
	public final static boolean isNullOrEmpty(final String needCheck) {
		return needCheck == null || needCheck.trim().isEmpty();
	}

	/**
	 * 参数检测，判断是否为 null 或者 "" 或者由空白组成
	 * 
	 * @param needCheck
	 *            : 待检测字符串(一个或多个)
	 * @return true: 输入字符串任一个 为 null 或者 ""<br>
	 *         ———— needCheck==null || needCheck.trim().equals("")<br>
	 *         false：输入字符串 全部 不为null不等于 ""
	 */
	public static boolean isNullOrEmpty(final String str1, final String str2) {
		return str1 == null || str1.trim().isEmpty() || str2 == null || str2.trim().isEmpty();
	}

	/**
	 * 参数检测，判断是否为 null 或者 "" 或者由空白组成
	 * 
	 * @param needCheck
	 *            : 待检测字符串(一个或多个)
	 * @return true: 输入字符串任一个 为 null 或者 ""<br>
	 *         ———— needCheck==null || needCheck.trim().equals("")<br>
	 *         false：输入字符串 全部 不为null不等于 ""
	 */
	public static boolean isNullOrEmpty(final String str1, final String str2, final String str3) {
		return str1 == null || str1.trim().isEmpty() || str2 == null || str2.trim().isEmpty() || str3 == null || str3.trim().isEmpty();
	}

	/**
	 * 参数检测，判断是否为 null 或者 "" 或者由空白组成
	 * 
	 * @param needCheck
	 *            : 待检测字符串(一个或多个)
	 * @return true: 输入字符串任一个 为 null 或者 ""<br>
	 *         ———— needCheck==null || needCheck.trim().equals("")<br>
	 *         false：输入字符串 全部 不为null不等于 ""
	 */
	public static boolean isNullOrEmpty(final String str1, final String str2, final String str3, final String str4) {
		return str1 == null || str1.trim().isEmpty() || str2 == null || str2.trim().isEmpty() || str3 == null || str3.trim().isEmpty() || str4 == null || str4.trim().isEmpty();
	}

	/**
	 * 参数检测，判断是否为 null 或者 "" 或者由空白组成
	 * 
	 * @param needCheck
	 *            : 待检测字符串(一个或多个)
	 * @return true: 输入字符串任一个 为 null 或者 ""<br>
	 *         ———— needCheck==null || needCheck.trim().equals("")<br>
	 *         false：输入字符串 全部 不为null不等于 ""
	 */
	public static boolean isNullOrEmpty(String... needCheck) {
		for (String curr : needCheck) {
			if (curr == null || curr.trim().isEmpty()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断是否是数字，含null与""的验证
	 * 
	 * @return true: 数字 false：含有其他字符
	 */
	public static boolean isNumeric(String str) {
		if (str == null || "".equals(str)) {
			return false;
		}
		for (int i = str.length(); --i >= 0;) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}

	public static String getSerialNo() {
		return UUID.randomUUID().toString();
	}

	/** 
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, Object> params) {

        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        String prestr = "";

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key).toString();

            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }

        return prestr;
    }
    
    /** 
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createCacheLinkString(Map<String, Object> params) {

    	Iterator<Entry<String, Object>> it = params.entrySet().iterator();
        while(it.hasNext()){
            Entry<String, Object> entry=it.next();
            Object key = entry.getValue();
            if(Integer.valueOf("0").equals(key) ||key == null ){
                it.remove();        //OK 
            }
        }
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        String prestr = "";

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key).toString();

            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr = prestr + key + "_" + value;
            } else {
                prestr = prestr + key + "_" + value + "_";
            }
        }

        return prestr;
    }
    @SuppressWarnings("unchecked")
    public static <E> List<E> converterStringArrayToOtherArray(List<String> source, E e){
        List<E> result = Lists.newArrayList();
        if(null == source){
            return null;
        }
        String c = e.getClass().getCanonicalName();
        Method method = null;
        for(String s:source){
            try {
                switch (c) {
                    case "java.lang.Integer":
                        method = e.getClass().getMethod("parseInt", s.getClass());
                        break;
                    case "java.lang.Float":
                        method = e.getClass().getMethod("parseFloat", s.getClass());
                        break;
                    case "java.lang.Double":
                        method = e.getClass().getMethod("parseDouble", s.getClass());
                        break;
                    case "java.lang.Long":
                        method = e.getClass().getMethod("parseLong", s.getClass());
                        break;
                    default:
                        break;
                }
                if(null != method){
                    result.add((E)(method.invoke(new Class[]{e.getClass()}, s)));
                }
            } catch (NoSuchMethodException | SecurityException e1) {
                logger.error("string converter error,String to "+ e.getClass(), e1);
            } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e2){
            	logger.error("method invoke error"+ e.getClass(), e2);
            }
        }
        return result;
    }

	/**
	 * 字符串转化整形
	 * 排空 可认定默认值
	 * 默认值：字符串不符合转化要求时的返回值
	 * @param srcStr 来源字符串
	 * @param defaultInt 转化默认值
	 * @return
	 */
	public static Integer toInteger(String srcStr, Integer defaultInt){
		if (defaultInt == null){
			defaultInt = 0;
		}
		if (StringUtils.isNumeric(srcStr)){
			return Integer.valueOf(srcStr);
		}
		return defaultInt;
	}
	/**
	 * 脱敏处理
	 * @param str      需脱敏str
	 * @param start  从第几位开始
	 * @param end   到多少位结束
	 * @param count 多少颗星->星星一颗两颗三颗四颗连成线
	 * @Author hecs
	 * @Return java.lang.String
	 * @Date 2018/10/12 17:49
	 */
	public static String asterisk (String str, int start, int end, int count) {
		if(StringUtils.isBlank(str)){
			return "";
		}
		StringBuffer result = new StringBuffer();
		int length = str.length();
		if (start <= length ) {
			result.append(str.substring(0, start));
		} else {
			result.append(str.substring(0, length));
		}
		for (int i=0; i<count; i++) {
			result.append("*");
		}
		if (end <= length ) {
			result.append(str.substring(length-end, length));
		} else {
			result.append(str.substring(0, length));
		}
		return result.toString();
	}

    /**
     * 下划线转驼峰法(默认小驼峰)
     *
     * @param line
     *            源字符串
     * @param smallCamel
     *            大小驼峰,是否为小驼峰(驼峰，第一个字符是大写还是小写)
     * @return 转换后的字符串
     */
    public static String underline2Camel(String line, boolean ... smallCamel) {
        if (line == null || "".equals(line)) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        Pattern pattern = Pattern.compile("([A-Za-z\\d]+)(_)?");
        Matcher matcher = pattern.matcher(line);
        //匹配正则表达式
        while (matcher.find()) {
            String word = matcher.group();
            //当是true 或则是空的情况
            if((smallCamel.length ==0 || smallCamel[0] ) && matcher.start()==0){
                sb.append(Character.toLowerCase(word.charAt(0)));
            }else{
                sb.append(Character.toUpperCase(word.charAt(0)));
            }

            int index = word.lastIndexOf('_');
            if (index > 0) {
                sb.append(word.substring(1, index).toLowerCase());
            } else {
                sb.append(word.substring(1).toLowerCase());
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
//        List<String> s = Lists.newArrayList();
//        s.add("1.2");
//        s.add("3.4");
//        System.out.println(converterStringArrayToOtherArray(s, Float.valueOf("1")));
		System.out.println(asterisk("郑少秋",1,1,1));
	}
}
